package com.ceres.oauth.controller;

import com.ceres.entity.Result;



import com.ceres.login.pojo.User;
import com.ceres.oauth.service.AuthUserService;
import com.ceres.oauth.util.AuthToken;
import com.ceres.oauth.util.CookieUtil;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/oauth/user")
public class AuthUserController {

    @Autowired
    private AuthUserService authService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Value("${auth.clientId}")
    private String clientId;

    @Value("${auth.clientSecret}")
    private String clientSecret;

    @Value("${auth.cookieDomain}")
    private String cookieDomain;

    @Value("${auth.cookieMaxAge}")
    private int cookieMaxAge;


    @RequestMapping("/toLogin")
    public String toLogin(@RequestParam(value = "FROM",required = false,defaultValue = "") String from, Model model){
        model.addAttribute("from",from);
        return "login";
    }


    @RequestMapping("/login")
    @ResponseBody
    public Result login(String username, String password, HttpServletResponse response){
//        校验参数
//        if (StringUtils.isEmpty(username)){
//            throw new RuntimeException("用户名或密码错误");
//        }
//        if (StringUtils.isEmpty(password)){
//            throw new RuntimeException("用户名或密码错误");
//        }
        //根据登录名获取管理员信息
        User user=authService.findByUsername(username);
        //获取redis中对String字符串操作的对象
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        //boos为判断redis中是否有此key存在
        Boolean boos;
        String keyword = "user" + user.getUsername();

        if (user==null|| user.getStatus().equals("2")){
            //账号密码错误
            return new Result(false, 3002);
        }
        //判断时间是否过期
        if (authService.findDateByusername(username).before(new Date())) {
            //账号到期
            return new Result(false,3005);
        }

        //判断账号状态 0:被锁定，1:启用

        //账号被锁定
        if (user.getStatus().equals("0")){
            //账号被锁定
            return new Result(false, 3003);
        }
        //对密码进行校验
        boolean boo = BCrypt.checkpw(password, user.getPassword());
        if (!boo){
            //验证此key是否存在
            boos = redisTemplate.hasKey(keyword);
            if (boos) {
                //如果boos为true,则证明redis中有此key,获取key的数值并加1
                Integer inte = Integer.parseInt(valueOperations.get(keyword));
                inte++;
                valueOperations.set(keyword, inte + "");
            } else {
                //boos为flase,则证明redis中没有此key,密码是第一次错误,故走以下逻辑
                valueOperations.set(keyword, 1 + "");
                //redis中设置key的过期时间 30分钟
                redisTemplate.expire(keyword, 1800, TimeUnit.SECONDS);
            }
            //判断错误次数,大于等于5次锁定
            if (Integer.parseInt(valueOperations.get(keyword)) >= 5) {
                //锁定用户
                authService.editUserStatus(username);
            }
            return  new Result(false, 3002);
        }
        //如果密码相同，则看redis中是否有错误次数，如果有则删除
        boos = redisTemplate.hasKey(keyword);
        if (boos) {
            redisTemplate.delete(keyword);
        }
        //初次登录判断
        //判断密码是不是123456
        if (BCrypt.checkpw("123456", user.getPassword())) {
            //判断是否是管理员
            if (authService.findRoleByUsername(username).contains(2)) {
                //申请令牌 authtoken
                AuthToken authToken = authService.login(username, password, clientId, clientSecret);

                //将jti的值存入cookie中
                this.saveJtiToCookie(authToken.getJti(),response);

                //返回结果
                return new Result(true, 2000,authToken.getJti());
            } else {
                //初次登录
                //申请令牌 authtoken
                AuthToken authToken = authService.login(username, password, clientId, clientSecret);

                //将jti的值存入cookie中
                this.saveJtiToCookie(authToken.getJti(),response);

                //返回结果
                return new Result(true, 3004,authToken.getJti());
            }
        } else {
            //申请令牌 authtoken
            AuthToken authToken = authService.login(username, password, clientId, clientSecret);

            //将jti的值存入cookie中
            this.saveJtiToCookie(authToken.getJti(),response);

            //返回结果
            return new Result(true, 2000,authToken.getJti());
        }


    }

    //将令牌的断标识jti存入到cookie中
    private void saveJtiToCookie(String jti, HttpServletResponse response) {
        CookieUtil.addCookie(response,cookieDomain,"/","uid",jti,cookieMaxAge,false);
    }
}
